#!/bin/sh

apk_leaf() {
	printf "\nPackages that no one want: \n\n"

	while read -r package; do
		if /sbin/apk info -r "$package" | wc -l | grep -q 2; then
			echo "$package"
		fi
	done < /etc/apk/world
}

_gen_fzf_default_opts() {
	color00='#28211c'
	color01='#36312e'
	#color02='#5e5d5c'
	#color03='#666666'
	color04='#797977'
	#color05='#8a8986'
	color06='#9d9b97'
	#color07='#baae9e'
	#color08='#cf6a4c'
	#color09='#cf7d34'
	color0A='#f9ee98'
	#color0B='#54be0d'
	color0C='#afc4db'
	color0D='#5ea6ea'
	#color0E='#9b859d'
	#color0F='#937121'

	export FZF_DEFAULT_OPTS="
	  --color=bg+:$color01,bg:$color00,spinner:$color0C,hl:$color0D
	  --color=fg:$color04,header:$color0D,info:$color0A,pointer:$color0C
	  --color=marker:$color0C,fg+:$color06,prompt:$color0A,hl+:$color0D
	"

}

beginswith() { case $2 in
	"$1"*) true;; *) false;; esac; }
endswith() { case $2 in
	*"$1") true;; *) false;; esac; }

screenshot_area() {
	grimshot --notify save area - | cwebp -lossless -o "$HOME/Pictures/screen_$(date +%Y-%m-%dT%H:%M:%S).webp" -- -
}

screenshot_this_window() {
	grimshot --notify save active - | cwebp -lossless -o "$HOME/Pictures/screen_$(date +%Y-%m-%dT%H:%M:%S).webp" -- -
}

screenshot_window() {
	grimshot --notify save window - | cwebp -lossless -o "$HOME/Pictures/screen_$(date +%Y-%m-%dT%H:%M:%S).webp" -- -
}

screenshot_all() {
	grimshot --notify save screen - | cwebp -lossless -o "$HOME/Pictures/screen_$(date +%Y-%m-%dT%H:%M:%S).webp" -- -
}

toggle_wifi() {
	state=$(doas connmanctl technologies | grep wifi -A3 | grep Powered | cut -d '=' -f 2 |tr -d ' ')
	if [ "$state" = 'False' ]; then
		doas connmanctl enable wifi
		sleep 5
		doas /etc/init.d/connman restart
	else
		doas connmanctl disable wifi
	fi
	bar_all_once
}

datediff() {
	d1=$(date -d "$1" +%s)
	d2=$(date -d "$2" +%s)
	if [ "$d1" -gt "$d2" ]; then
		d=$(qalc -t -b '10 10' "$d1 - $d2")
	else
		d=$(qalc -t -b '10 10' "$d2 - $d1")
	fi
	d=$(qalc -t -b '10 10' "round($d / 86400)")
	if [ "$d" -eq 1 ]; then
		printf "%s day\n" "$d"
	else
		printf "%s days\n" "$d"
	fi
}

shuffle() {
	n=$1
	shuf -i "1-$n" -n "$n"
}

alarm() {
	echo "notify-send -u critical -i appointment-soon 'Alarm' '$2'; ffplay ~adam/Music/mps/cloister.ogg" | at "$1"
}

guakPosition() {
	width=$(swaymsg -t get_outputs | jq '.. | objects | select(.focused == true).current_mode.width')
	height=$(swaymsg -t get_outputs | jq '.. | objects | select(.focused == true).current_mode.height')
	scale=$(swaymsg -t get_outputs | jq '.. | objects | select(.focused == true).scale')
	w=$(echo "$width $scale / p" | dc)
	h=$(echo "$height $scale / 2.5 / p" | dc)
	move=$(echo "$height $scale / $h - 2 / p" | dc)
	swaymsg "[pid=${pid}] floating enable, resize set $w $h, move position center, move up $move px"
}

guakStart() {
	wezterm start --always-new-process >/dev/null 2>&1 &
	pid=$(jobs -p)
	echo "$pid" >/tmp/guak_pid
	i=0
	while [ "$i" -lt 50 ]
	do
		if (swaymsg -t get_tree --raw|grep -q "\"pid\": ${pid},"); then
      break
    fi
    i=$((i+=1))
    nanosleep 100000000
	done
	nanosleep 125
	guakPosition
}

guakIsVisible() {
	swaymsg -t get_tree --raw| jq '.nodes[].nodes[].floating_nodes[].visible' | grep -q true
}

guakToggle() {
	if guakIsVisible; then
		swaymsg "[pid=${pid}] move scratchpad"
	else
		swaymsg "[pid=${pid}] scratchpad show"
		guakPosition
	fi
}

guak() {
	set -x
	if [ -e "/tmp/guak_pid" ]; then
		pid=$(cat /tmp/guak_pid)
		if ! (ps -eopid | grep -q "$pid"); then
			guakStart
		else
			guakToggle
		fi
	else
		guakStart
	fi
}

hex2rgb() {
	hexinput=$(echo "$1"| tr '[:lower:]' '[:upper:]')
	if [ "$(echo "$hexinput" | cut -c1)" = '#' ]; then
		hexinput=$(echo "$hexinput" |cut -c2-)
	fi


	a=$(echo "$hexinput" | cut -c-2)
	b=$(echo "$hexinput" | cut -c3-4)
	c=$(echo "$hexinput" | cut -c5-6)

	r=$(qalc -t -s 'base 10' "0x$a")
	g=$(qalc -t -s 'base 10' "0x$b")
	b=$(qalc -t -s 'base 10' "0x$c")

	echo "$r" "$g" "$b"
}

import_gsettings() {
	for pair in "$@"; do
		gKey=$(echo "$pair" | cut -d':' -f1)
		name=$(echo "$pair" | cut -d':' -f2)
		value=$(grep "$name" "${XDG_CONFIG_HOME:-$HOME/.config}"/gtk-3.0/settings.ini | cut -d'=' -f2)
		gsettings set org.gnome.desktop.interface "$gKey" "$value"
	done
}

pad() {
	num=$1
	while [ "${#num}" -lt "$2" ]
	do
		num="0$num"
	done
	echo "$num"
}

now() {
	now=$(qalc -t -b '12' "int(($(date +%H) * 3600000000000 + $(date +%M) * 60000000000 + $(date +%S) * 1000000000 + $(date +%N)) / 1000000000 * 144 / 25)")
	now=$(pad "$now" 6)

	hora=$(echo "$now" | colrm 3)
	dunatim=$(echo "$now" | colrm 5 | rev | colrm 3 | rev)
	tim=$(echo "$now" | rev | colrm 3 | rev)
	if [ "$1" = "-t" ]; then
		printf "{\"text\": \"%s.%s\"}\n" "$hora" "$dunatim"
	else
		printf "{\"text\": \"%s.%s.%s\"}\n" "$hora" "$dunatim" "$tim"
	fi
}

backlight() {
	if [ "$1" = '-' ]; then
		cmd='-U'
	elif [ "$1" = '+' ]; then
		cmd='-A'
	fi
	brillo "$cmd" 5
	brillo -G | cut -d'.' -f1 > /tmp/wob.sock
	sleep 1
	printf '' > /tmp/wob.sock
}

streamDwd() {
	if [ $# -lt 1 ]; then
		min=1800
	else
		min=$(($1 * 60))
	fi

	echo "Downloading for $min seconds"

	mkdir -p /home/adam/Downloads/streams/melo
	name=$(date '+%Y-%m-%dT%H:%M')

	ffmpeg -i 'http://r.dcs.redcdn.pl/sc/o2/Eurozet/live/meloradio.livx?audio=5' -t "$min" "/home/adam/Downloads/streams/melo/$name.ogg"
}

ffmpegQ() {
	height=$(ffprobe "$*" -show_entries stream=height -of csv=p=0 -v error -select_streams v:0)

	if [ "$height" -lt 480 ]; then
		echo 37
	elif [ "$height" -lt 720 ]; then
		echo 35
	elif [ "$height" -lt 1080 ]; then
		echo 34
	else
		echo 33
	fi
}

toVP9() {
	Q=$(ffmpegQ "$1")
	set -x
	ffmpeg -i "$1" -crf "$Q" -threads 16 -b:v 0 -c:v libvpx-vp9 -r 25 "${1%.*}.vp9.webm"
}

toAV1() {
	Q=$(ffmpegQ "$1")
	set -x
	ffmpeg -i "$1" -c:v libsvtav1 -crf "$Q" -r 25 "${1%%.*}.av1.webm"
	# testme ffmpeg -i input.mp4 -c:a copy -c:v libsvtav1 -preset 10 -r 25 -threads 16 -crf 17 svtav1_test.mp4
	#ffmpeg -i "$1" -crf "$Q" -threads 16 -b:v 0 -c:v libaom-av1 -r 25 -strict experimental -tile-columns 2 -pix_fmt yuv420p "${1%%.*}.av1.webm"
}

selectSoundCard() {
	if [ -f /tmp/asoundrc_usb ] && [ "$(cat /tmp/asoundrc_usb)" != '' ]; then
		echo 'PCM'
		exit 0
	fi
	# TODO if headphones connected -> echo 'Headphone'; exit 0
	# TODO if hdmi connected -> echo ?; exit 0
	echo 'Speaker'
}

volume() {
	if command -v pactl >/dev/null 2>&1; then
		if [ "$1" = '+' ]; then
			pactl set-sink-volume @DEFAULT_SINK@ +5%
		elif [ "$1" = '-' ]; then
			pactl set-sink-volume @DEFAULT_SINK@ -5%
		elif [ "$1" = 't' ]; then
			pactl set-sink-mute @DEFAULT_SINK@ toggle
		fi
		mute=$(pactl get-sink-mute @DEFAULT_SINK@ | cut -d ' ' -f2)
		volume=$(pactl get-sink-volume @DEFAULT_SINK@ | head -n1 | cut -d '/' -f2 | tr -d ' %')
		if [ "$mute" = 'yes' ]; then
			echo '0' >/tmp/wob.sock
		else
			echo "$volume" >/tmp/wob.sock
		fi
		printf '' >/tmp/wob.sock
	else
		# shellcheck disable=2012
		output=$(basename "$(ls -l ~/.config/alsa/asoundrc-default | cut -d '>' -f2 | tr -d ' ')")
		if [ "$output" = 'null' ]; then
			amixer -M sset Master on
			amixer -M sset Master 100%
			cmd='-M sset'
			ctl=$(selectSoundCard)
		elif [ "$output" = 'asoundrc-bluealsa' ]; then
			cmd='-D bluealsa sset'
			ctl="\"$(amixer -D bluealsa scontrols | grep 'A2DP' | sed -E "s/^[^']*'//" | sed "s/',0//")\""
		else
			exit 1
		fi

		if [ "$1" = '+' ]; then
			result=$(eval "amixer $cmd $ctl 5%+")
		elif [ "$1" = '-' ]; then
			result=$(eval "amixer $cmd $ctl 5%-")
		elif [ "$1" = 't' ]; then
			result=$(eval "amixer $cmd $ctl toggle")
		fi
		result=$(echo "$result" | sed -En 's/.*\[([0-9]+)%\].*/\1/p' | head -n1)
		if amixer sget "$ctl" | grep -qF '[off]'; then
			result="$result muted"
		fi
		echo "$result" >/tmp/wob.sock
		sleep 1
		printf '' >/tmp/wob.sock
	fi
}

lastmod() {
	if [ "$1" = '' ]; then
		dir="."
	else
		dir="$1"
	fi
	find "$dir" -type f -print0 | xargs -0 stat --format '%Y :%y %n' | sort -nr | cut -d: -f2- | head -n1
}

backup() {
	set -ex

	if [ "$1" = 'mymlan' ]; then
		if [ "$(id -u)" -eq 0 ]; then
			printf "don’t run as root"
			exit 1
		fi
		rsync -rtP --delete /media/usb/adam/H500/Mårran/ /media/usb/adam/Mymlan/
	fi

	if [ "$1" = 'daily' ]; then
		case "$(hostname)" in
			mycroft)
				if [ "$(id -nu)" != 'adam' ]; then
					printf "run as adam"
					exit 1
				fi

				name="backup_$(date '+%Y%m%dT%H%M')"

				[ -f /tmp/1000-runtime-dir/keybase/keybased.sock ] || keybase service >/dev/null 2>&1 &
				doas modprobe fuse
				[ -d /keybase/ ] || kbfsfuse >/dev/null 2>&1 &
				while ! cd /keybase 2>/dev/null
				do
					sleep 2
				done
				cd

				find /keybase/private/bquiet/backup/mycroft/ -type f -iname 'backup_*.tar' -mtime '+6' -exec rm {} \;

				# git-remotes in ~/Code/dwd
				tar cf "/keybase/private/bquiet/backup/mycroft/${name}.tar" --exclude dwd ~/Code/ ~/Documents/ ~/Downloads/ ~/Pictures/ ~/Templates/ /etc/runlevels /etc/connman/ /etc/doas.conf /etc/udev /etc/udisks2/ /etc/sysctl.conf /etc/hostname /etc/apk/world
			;;
			DeepThought)
				if [ "$(id -nu)" != 'backup' ]; then
					printf "run as backup"
					exit 1
				fi

				set -x
				date
				name="backup_$(date '+%Y%m%dT%H%M')"
				cmd="$1"

				infraFiles=$(doas -u infra /home/infra/backup "$cmd")
				wwwFiles=$(doas -u www /var/www/backup "$cmd")

				if [ -z "$cmd" ]; then
					find /keybase/private/bquiet/backup/deepthought/ -type f -iname 'backup_*.tar' -mtime '+6' -exec rm {} \;

					eval "tar -cPlf /keybase/private/bquiet/backup/deepthought/${name}.tar backup $infraFiles $wwwFiles"
				fi
			;;
		esac
		exit 0
	fi

	if ! (id -Gn | grep -q backup); then
		printf "run as a member of group ‘backup’"
		exit 1
	fi

	case "$(hostname)" in
		mycroft)
			cd /
			doas btrfs subvolume snapshot -r / "root_$(date '+%Y%m%d')"
			doas btrfs send root_* | doas btrfs receive /media/usb/adam/H500/
			doas btrfs subvolume delete "root_$(date '+%Y%m%d')"
			cd /home || exit 1
			doas btrfs subvolume snapshot -r /home/ "home_$(date '+%Y%m%d')"
			doas btrfs send home_* | doas btrfs receive /media/usb/adam/H500/
			doas btrfs subvolume delete "home_$(date '+%Y%m%d')"
		;;
	esac
}

connected() {
  if iwctl station list | grep wlan0 | grep -q 'connected'; then
    return 0
  else
    return 1
  fi
}

shouldBackupNow() {
  if [ ! -f ~/.cache/lastBackup ]; then
    return 0
  fi

  now=$(date '+%s')
  then=$(cat ~/.cache/lastBackup)

  test $((now - then)) -gt 86400
}

shouldPassNow() {
  cd ~/Code/current/joeblack || return 1
  passLastDate=$(git log --date=unix | grep Date | tr -s ' ' |cut -d ' ' -f2- | head -n1)
  cd ~/.local/share/himitsu || return 1
  himitsuLastDate=$(git log --date=unix | grep Date | tr -s ' ' |cut -d ' ' -f2- | head -n1)
  test "$passLastDate" -lt "$himitsuLastDate"
}

network_backup() {
	if connected; then
	  shouldPassNow && notify-send -i backup -u critical 'JoeBlack should be run' 'There are changes to passwords since last JoeBlack sync'
	  shouldBackupNow && (
	    notify-send -i backup 'Running daily backup'
	    backup daily
	    notify-send -i backup 'Finished daily backup'
	    date '+%s' >~/.cache/lastBackup
	  )
	fi

	ip monitor address | while read -r _
	do
	  if connected; then
	    shouldPassNow && notify-send -i backup -u critical 'JoeBlack should be run' 'There are changes to passwords since last JoeBlack sync'
	    shouldBackupNow && (
	      notify-send -i backup 'Running daily backup'
	      backup daily
	      notify-send -i backup 'Finished daily backup'
	      date '+%s' >~/.cache/lastBackup
	    )
	  fi
	done
}

bar_all_once() {
	~/.local/bin/bar_clock
	~/.local/bin/bar_battery -1
	~/.local/bin/bar_network -1
	bar_bluetooth
}

bt() {
	trap bar_bluetooth INT

	if [ "$1" = 'on' ]; then
		(
			ln -sf ~/.config/alsa/asoundrc-bluealsa ~/.config/alsa/asoundrc-default
			doas /usr/sbin/rfkill unblock bluetooth
			sleep 1
			bluetoothctl power on || (sleep 2; bluetoothctl power on)
			sleep 1
			bluetoothctl connect 9E:53:D5:1C:FE:07
			amixer -D bluealsa sset "$(amixer -D bluealsa scontrols | grep 'A2DP' | sed -E "s/^[^']*'//" | sed "s/',0//")" 50% >/dev/null
		)
	elif [ "$1" = 'off' ]; then
		bluetoothctl power off
		ln -sf /dev/null ~/.config/alsa/asoundrc-default
	else
		bluetoothctl show | grep Powered | cut -f2
		bluetoothctl info | grep -E '(Alias|Connected)' | cut -f2
	fi

	bar_bluetooth
}

fd() {
	if [ "$(git rev-parse --show-toplevel 2>/dev/null)" = '/home/adam' ]; then
		/usr/bin/fd -I "$@"
	else
		/usr/bin/fd "$@"
	fi
}

luakit() {
	. "$HOME/.config/sh/variables"

	/usr/bin/luakit "$@"
	cd ~/.local/share/luakit/ || exit 1
	sqlite3 cookies.db 'delete from moz_cookies;'
	sqlite3 history.db 'delete from history;'
	sqlite3 downloads.db 'delete from downloads;'
	rm -rf ./local_storage/*
	rm -rf ./indexeddb/*
	echo '{{["command"]={2},},{},}' > ./command-history
}

mntblk() {
	set -e

	# shellcheck disable=SC2010
	disks=$(ls -l /dev/disk/by-uuid/ | grep -v dm | grep -v nvme0n1 | cut -d '>' -f 2 | tail -n+2 | cut -d '/' -f 3)
	labels=$(ls -l /dev/disk/by-label/)

	if [ -z "$disks" ]; then
		echo "No disks attached"
		exit
	fi

	disk_labels=$(for disk in $disks
	do
		mountpoint=$(mount | grep "$disk" | cut -d ' ' -f 3- | rev | cut -d ' ' -f 4- | rev)
		label=$(echo "$labels" | grep "$disk" | awk -F '->' '{print $1}' | tr -s ' ' | cut -d ' ' -f 9)
		if [ -z "$label" ]; then
			entry="$disk�$disk"
		else
			entry="$disk�$label"
		fi
		if [ "$mountpoint" ]; then
			entry="$entry ($mountpoint)"
		fi
		echo "$entry"
	done)

	result=$(echo "$disk_labels" | fzf -m -d '�' --with-nth 2)
	if [ -z "$result" ]; then
		exit
	fi

	label=$(echo "$result" | awk -F '�' '{print $2}')
	disk=$(echo "$result" | awk -F '�' '{print $1}')
	path="/dev/$disk"

	if mount | grep -q "$path"; then
		action='unmount'
	else
		action='mount'
	fi

	udisksctl "$action" -b "$path"

	if [ "$action" = 'unmount' ] && ! [ "$1" = '-s' ]; then
		echo "Ejecting $path"
		doas eject "$path"
	fi
}

pass() {
	case "$1" in
		'sync')
			cd ~/.local/share/himitsu/ || (echo 'no himitsu data dir'; exit 1)
			echo 'pulling changes'
			git pull
			echo 'pushing changes'
			git push
			cd ~/Code/current/joeblack || exit 0
			echo '# syncing Joe Black'
			./encode
			git add payload
			git commit -m "$(date '+%Y%m%dT%H%M')"
			git push
			;;
		*)
			echo 'pass sync'
			;;
	esac
}

rip() {
	cd-paranoia -Q 2>&1 |
	grep "^ *[1-9]" | 
	sed -e 's/^ *\|\..*//g' | 
	while read -r t; do
	  cd-paranoia "$t" - | ffmpeg -i pipe: "rip_$t.flac";
	done
}

run() {
	app_paths="$(find /usr/share/applications -name '*.desktop') $(find "$HOME/.local/share/applications" -name '*.desktop')"
	apps=$(for app in $app_paths
	do
		basename "$app"
	done | sort -u)

	result=$(for app in $apps
	do
		if [ -f "$HOME/.local/share/applications/$app" ]; then
			path="$HOME/.local/share/applications/$app"
		else
			path="/usr/share/applications/$app"
		fi
		name=$(grep -E '^Name=' "$path" | head -n1 | cut -d '=' -f 2)
		commands=$(grep -E '^Name=|^Exec' "$path" | sed 's/ %.//' | cut -d '=' -f2- | awk '(NR-1)%2 == 0 { printf("%s%s", $0, "�") }; (NR-1)%2 == 1 { print }')
		if [ -z "$commands" ]; then
			continue
		fi
		if [ "$(echo "$commands" | wc -l)" -gt 1 ]; then
		echo "$commands" | while read -r exec_command
			do
				if [ "$(echo "$exec_command" | sed 's/�.*//')" = "$name" ]; then
					echo "$exec_command"
				else
					echo "$name, $exec_command"
				fi
			done
		else
			echo "$commands"
		fi
	done | uniq | fzf -m -d '�' --with-nth 1)

	exec $(echo "$result" | sed 's/.*�//') >/dev/null 2>&1 &
}

view() {
	# TODO add gemini
	if beginswith 'http://' "$1" || beginswith 'https://' "$2"; then
		luakit "$1"
		exit
	fi

	mime=$(file -i "$1" | rev | cut -d ':' -f1 | rev | cut -d ';' -f1 | tr -d ' ')
	charset=$(file -i "$1" | rev | cut -d ':' -f1 | rev | cut -d ';' -f2 | tr -d ' ')
	case $mime in
		text/*) bat -f "$1" ;;
		image/*) setsid swayimg "$1" >/dev/null 2>&1 & ;;
		video/*) setsid fun mpv "$1" >/dev/null 2>&1 & ;;
		audio/*) setsid fun mpa "$1" >/dev/null 2>&1 & ;;
		application/json) bat -f "$1" ;;
		application/javascript) bat -f "$1" ;;
		application/x-subrip) bat -f "$1" ;;
		application/pdf) setsid zathura "$1" >/dev/null 2>&1 & ;;
		application/epub+zip) setsid zathura "$1" >/dev/null 2>&1 & ;;
		application/zip) unzip -l "$1" ;;
		application/pgp-keys)
			if [ "$charset" = 'us-ascii' ]; then
				bat -f "$1"
			else
				hexyl "$1"
			fi
		;;
		application/x-bzip2|application/gzip|application/x-tar) tar tvf "$1" ;;
		*) hexyl "$1" ;;
	esac
}

preview() {
	mime=$(file -i "$1" | rev | cut -d ':' -f1 | rev | cut -d ';' -f1 | tr -d ' ')
	charset=$(file -i "$1" | rev | cut -d ':' -f1 | rev | cut -d ';' -f2 | tr -d ' ')
	case $mime in
		text/*) view "$1" ;;
		image/*)
			chafa -f sixel -s "$2x$3" --animate false "$1"
			exit 1
		;;
		video/*)
			mkdir -p "$HOME/.cache/thumbnails"
			chksum=$(meowsum "$1" | cut -d ' ' -f 1)
			if [ ! -f "$HOME/.cache/thumbnails/$chksum.png" ]; then
				ffmpegthumbnailer -i "$1" -s 0 -o "$HOME/.cache/thumbnails/$chksum.png"
			fi
			chafa -f sixel -s "$2x$3" --animate false "$HOME/.cache/thumbnails/$chksum.png"
			exit 1
		;;
		audio/*) ffprobe "$1" 2>&1;;
		application/json) view "$1" ;;
		application/javascript) view "$1" ;;
		application/pdf)
			mkdir -p "$HOME/.cache/thumbnails"
			chksum=$(meowsum "$1" | cut -d ' ' -f 1)
			if [ ! -f "$HOME/.cache/thumbnails/$chksum.png" ]; then
			 convert -density 150 -trim "$1[0]" -quality 100 -flatten -sharpen 0x1.0 "$HOME/.cache/thumbnails/$chksum.png"
			fi
			chafa -f sixel -s "$2x$3" --animate false "$HOME/.cache/thumbnails/$chksum.png"
			exit 1
		;;
		application/epub+zip) unzip -l "$1" ;;
		application/zip) view "$1" ;;
		application/pgp-keys) view "$1" ;;
		application/x-bzip2|application/gzip|application/x-tar) view "$1" ;;
		application/zstd)
			zstd -dfk "$1" -o /tmp/hgsdhsbfksabfasdfbjhbcsdygreyb.tar >/dev/null 2>&1
			tar tvf /tmp/hgsdhsbfksabfasdfbjhbcsdygreyb.tar
			rm /tmp/hgsdhsbfksabfasdfbjhbcsdygreyb.tar
		;;
		*) view "$1" ;;
	esac
}

edit() {
	mime=$(file -i "$1" | rev | cut -d ':' -f1 | rev | cut -d ';' -f1 | tr -d ' ')
	charset=$(file -i "$1" | rev | cut -d ':' -f1 | rev | cut -d ';' -f2 | tr -d ' ')
	case $mime in
		text/*) hx "$1" ;;
		image/*) setsid gimp "$1" >/dev/null 2>&1 & ;;
		video/*) setsid kdenlive  "$1" >/dev/null 2>&1 & ;;
		audio/*) setsid audacity "$1" >/dev/null 2>&1 & ;;
		application/json) hx "$1" ;;
		application/javascript) hx "$1" ;;
		application/pdf) setsid gimp "$1" >/dev/null 2>&1 & ;;
		application/epub+zip) setsid sigil "$1" >/dev/null 2>&1 & ;;
		application/zip|application/x-bzip2|application/gzip|application/x-tar) setsid file-roller "$1" >/dev/null 2>&1 & ;;
	esac
}

ws() {
	if stat "$HOME/Pictures/wallpapers/$(hostname)_w$1.webp" >/dev/null 2>&1; then
		wallpaper="$HOME/Pictures/wallpapers/$(hostname)_w$1.webp"
	else
		wallpaper="$HOME/Pictures/wallpapers/$(hostname).webp"
	fi

	killall swaybg
	swaybg -i "$wallpaper" -m fill >/dev/null 2>&1 &
	#nanosleep 100000000
	swaymsg workspace "$1"
}

photosArchive() {
	IFS=''

	author="Adam Evyčędo <photos@apiote.xyz>"
	copyright="CC BY-SA"

	while [ $# -gt 0 ]
	do
		if [ "$1" = "--author" ]; then
			shift
			author=$1
		fi
		if [ "$1" = "--copyright" ]; then
			shift
			copyright=$1
		fi
		if [ "$1" = "--no-exif" ]; then
			noExif=true
		fi
		if [ "$1" = "--no-rename" ]; then
			noRename=true
		fi
		shift
	done

	if [ "$noRename" ]; then
		printf "No renaming\n"
	else
		printf "Renaming\n"
		rename '.JPG' '.jpg' ./*.JPG
		exiv2 -F mv ./*.jpg

		rename '.MOV' '.mov' ./*.MOV
		for film in ./*.mov
		do
			filmName=$(ffprobe -show_entries format_tags=creation_time "$film" 2>/dev/null | grep TAG: | cut -d '.' -f1 | sed 's/TAG:creation_time=//' | sed -E 's/(-|:)//g' | sed 's/T/_/')
			mv "$film" "$filmName.mov"
		done
	fi

	if [ "$noExif" ]; then
		printf 'No exif\n'
	else
		printf "Setting exif data: %s, %s\n" "$author" "$copyright"
		exiv2 -da ./*.jpg
		exiv2 -M "set Exif.Image.Copyright $copyright" mo ./*.jpg
		exiv2 -M "set Exif.Image.Artist $author" mo ./*.jpg
	fi

	printf "Orienting\n"
	for x in ./*.jpg
	do
		convert -auto-orient "$x" "${x}_r"
	done

	printf "Removing oriented\n"
	for x in ./*_r
	do
		name=${x%_*}
		mv "$x" "$name"
	done

	printf "Encoding to webp\n"
	for x in ./*.jpg
	do
		name=${x%.*}
		cwebp "$x" -metadata all -o "${name}.webp" || (mv "$x" "$x.webp" && rm "${name}.webp")
	done

	printf "Encoding to webm\n"
	for x in ./*.mp4
	do
		toAV1 "$x"
	done

	printf "Checksum\n"
	sha512sum ./*.webp ./*.webm ./*.mkv > .checksum

	printf "Zipping\n"
	zip Result.zip ./*.webp ./*.webm ./*.mkv .checksum .description
}

photosJoin() {
	oldPath=$(pwd)
	mkdir /tmp/photosOne /tmp/photosTwo
	cp "$1" /tmp/photosOne
	cp "$2" /tmp/photosTwo
	cd /tmp/photosOne || exit 1
	unzip "$1"
	rm "$1"
	cd /tmp/photosTwo || exit 1
	unzip "$2"
	rm "$2"

	mkdir /tmp/photosResult
	cd /tmp/photosResult || exit 1
	cat /tmp/photosOne/.checksum /tmp/photosTwo/.checksum > .checksum
	cat /tmp/photosOne/.description /tmp/photosTwo/.description > .description
	rm /tmp/photosOne/.checksum /tmp/photosOne/.description
	rm /tmp/photosTwo/.checksum /tmp/photosTwo/.description
	mv /tmp/photosOne/* .
	mv /tmp/photosTwo/* .
	zip Result.zip ./*.webp ./*.webm ./*.mkv .checksum .description
	cd "$oldPath" || exit 1
	mv /tmp/photosResult/Result.zip .
	rm -rf /tmp/photosOne /tmp/photosTwo /tmp/photosResult
}

filemanager() {
	LF_ICONS="\
tw=:\
st=:\
ow=:\
dt=:\
di=:\
fi=:\
ln=:\
or=:\
ex=:\
*.c=:\
*.cc=:\
*.clj=:\
*.coffee=:\
*.cpp=:\
*.css=:\
*.d=:\
*.dart=:\
*.erl=:\
*.exs=:\
*.fs=:\
*.go=:\
*.h=:\
*.hh=:\
*.hpp=:\
*.hs=:\
*.html=:\
*.java=:\
*.jl=:\
*.js=:\
*.json=:\
*.lua=:\
*.md=:\
*.php=:\
*.pl=:\
*.pro=:\
*.py=:\
*.rb=:\
*.rs=:\
*.scala=:\
*.ts=:\
*.vim=:\
*.cmd=:\
*.ps1=:\
*.sh=:\
*.bash=:\
*.zsh=:\
*.fish=:\
*.tar=:\
*.tgz=:\
*.arc=:\
*.arj=:\
*.taz=:\
*.lha=:\
*.lz4=:\
*.lzh=:\
*.lzma=:\
*.tlz=:\
*.txz=:\
*.tzo=:\
*.t7z=:\
*.zip=:\
*.z=:\
*.dz=:\
*.gz=:\
*.lrz=:\
*.lz=:\
*.lzo=:\
*.xz=:\
*.zst=:\
*.tzst=:\
*.bz2=:\
*.bz=:\
*.tbz=:\
*.tbz2=:\
*.tz=:\
*.deb=:\
*.rpm=:\
*.jar=:\
*.war=:\
*.ear=:\
*.sar=:\
*.rar=:\
*.alz=:\
*.ace=:\
*.zoo=:\
*.cpio=:\
*.7z=:\
*.rz=:\
*.cab=:\
*.wim=:\
*.swm=:\
*.dwm=:\
*.esd=:\
*.avif=:\
*.webp=:\
*.jpg=:\
*.jpeg=:\
*.mjpg=:\
*.mjpeg=:\
*.gif=:\
*.bmp=:\
*.pbm=:\
*.pgm=:\
*.ppm=:\
*.tga=:\
*.xbm=:\
*.xpm=:\
*.tif=:\
*.tiff=:\
*.png=:\
*.svg=:\
*.svgz=:\
*.mng=:\
*.pcx=:\
*.mov=:\
*.mpg=:\
*.mpeg=:\
*.m2v=:\
*.mkv=:\
*.webm=:\
*.ogm=:\
*.mp4=:\
*.m4v=:\
*.mp4v=:\
*.vob=:\
*.qt=:\
*.nuv=:\
*.wmv=:\
*.asf=:\
*.rm=:\
*.rmvb=:\
*.flc=:\
*.avi=:\
*.fli=:\
*.flv=:\
*.gl=:\
*.dl=:\
*.xcf=:\
*.xwd=:\
*.yuv=:\
*.cgm=:\
*.emf=:\
*.ogv=:\
*.ogx=:\
*.aac=:\
*.au=:\
*.flac=:\
*.m4a=:\
*.mid=:\
*.midi=:\
*.mka=:\
*.mp3=:\
*.mpc=:\
*.ogg=:\
*.ra=:\
*.wav=:\
*.oga=:\
*.opus=:\
*.spx=:\
*.xspf=:\
*.pdf=:\
*.nix=:" lf

	find ~/.cache/thumbnails/ -atime +7 -exec rm {} \;
}

update_git() {
	set -e

	pkgs="$1"
	if [ "$pkgs" = '' ]; then
		echo package not specified
		exit 1
	fi
	if [ "$pkgs" = 'all' ]; then
		pkgs='libasciidoc glider doh'
	fi

	# TODO git clone if not exists
	cd ~/Code/dwd
	for pkg in $pkgs
	do
		case "$pkg" in
			'glider')
				cd ./glider
				git checkout master
				git reset --hard HEAD
				cat <<END >features.patch
	diff --git a/feature.go b/feature.go
	index 21b49fc..68aaf6b 100644
	--- a/feature.go
	+++ b/feature.go
	@@ -5,23 +5,23 @@ import (
	 	// _ "github.com/nadoo/glider/service/xxx"
 
	 	// comment out the protocols you don't need to make the compiled binary smaller.
	-	_ "github.com/nadoo/glider/proxy/http"
	-	_ "github.com/nadoo/glider/proxy/kcp"
	-	_ "github.com/nadoo/glider/proxy/mixed"
	-	_ "github.com/nadoo/glider/proxy/obfs"
	-	_ "github.com/nadoo/glider/proxy/pxyproto"
	-	_ "github.com/nadoo/glider/proxy/reject"
	-	_ "github.com/nadoo/glider/proxy/smux"
	-	_ "github.com/nadoo/glider/proxy/socks4"
	+	// _ "github.com/nadoo/glider/proxy/http"
	+	// _ "github.com/nadoo/glider/proxy/kcp"
	+	// _ "github.com/nadoo/glider/proxy/mixed"
	+	// _ "github.com/nadoo/glider/proxy/obfs"
	+	// _ "github.com/nadoo/glider/proxy/pxyproto"
	+	// _ "github.com/nadoo/glider/proxy/reject"
	+	// _ "github.com/nadoo/glider/proxy/smux"
	+	// _ "github.com/nadoo/glider/proxy/socks4"
	 	_ "github.com/nadoo/glider/proxy/socks5"
	-	_ "github.com/nadoo/glider/proxy/ss"
	-	_ "github.com/nadoo/glider/proxy/ssh"
	-	_ "github.com/nadoo/glider/proxy/ssr"
	-	_ "github.com/nadoo/glider/proxy/tcp"
	+	// _ "github.com/nadoo/glider/proxy/ss"
	+	// _ "github.com/nadoo/glider/proxy/ssh"
	+	// _ "github.com/nadoo/glider/proxy/ssr"
	+	// _ "github.com/nadoo/glider/proxy/tcp"
	 	_ "github.com/nadoo/glider/proxy/tls"
	-	_ "github.com/nadoo/glider/proxy/trojan"
	-	_ "github.com/nadoo/glider/proxy/udp"
	-	_ "github.com/nadoo/glider/proxy/vless"
	-	_ "github.com/nadoo/glider/proxy/vmess"
	+	// _ "github.com/nadoo/glider/proxy/trojan"
	+	// _ "github.com/nadoo/glider/proxy/udp"
	+	// _ "github.com/nadoo/glider/proxy/vless"
	+	// _ "github.com/nadoo/glider/proxy/vmess"
	 	_ "github.com/nadoo/glider/proxy/ws"
	 )
	diff --git a/feature_linux.go b/feature_linux.go
	index bbe2eff..1866395 100644
	--- a/feature_linux.go
	+++ b/feature_linux.go
	@@ -1,12 +1,12 @@
	 package main
 
	 import (
	-	// comment out the services you don't need to make the compiled binary smaller.
	-	_ "github.com/nadoo/glider/service/dhcpd"
	+// comment out the services you don't need to make the compiled binary smaller.
	+// _ "github.com/nadoo/glider/service/dhcpd"
 
	-	// comment out the protocols you don't need to make the compiled binary smaller.
	-	_ "github.com/nadoo/glider/proxy/redir"
	-	_ "github.com/nadoo/glider/proxy/tproxy"
	-	_ "github.com/nadoo/glider/proxy/unix"
	-	_ "github.com/nadoo/glider/proxy/vsock"
	+// comment out the protocols you don't need to make the compiled binary smaller.
	+// _ "github.com/nadoo/glider/proxy/redir"
	+// _ "github.com/nadoo/glider/proxy/tproxy"
	+// _ "github.com/nadoo/glider/proxy/unix"
	+// _ "github.com/nadoo/glider/proxy/vsock"
	 )
END

				git apply features.patch
				go build -v -ldflags "-s -w"
			;;
			'doh')
				cd ./dns-over-https/
				git checkout master
				git reset --hard HEAD
				git pull
				/usr/bin/make binary
				# doas sv stop doh
				# doas cp doh-client/doh-client /usr/local/bin/
				# doas chmod 755 /usr/local/bin/doh-client
				# doas sv start doh
				/usr/bin/make clean
				cd ../
			;;
			'libasciidoc')
				cd ./libasciidoc/
				git checkout master
				git reset --hard HEAD
				git pull
				# export PATH="$HOME/.go/bin/:$PATH"
				/usr/bin/make build
				# doas cp ./bin/libasciidoc /usr/local/bin/asciidoc
				# doas chmod 755 /usr/local/bin/asciidoc
				cd ../
			;;
			'doas')
				apk add make byacc linux-pam-dev
				cd ./doas/
				git checkout master
				git reset --hard HEAD
				git pull
				# export PATH="$HOME/.go/bin/:$PATH"
				./configure --with-pam  # TODO with time
				/usr/bin/make build
				# doas cp ./doas /usr/local/bin/doas
				# doas chmod 755 /usr/local/bin/doas
				# doas chmod u+s /usr/local/bin/doas
				cd ../
			;;
		esac
	done
}

waterInit() {
	mkdir -p "$HOME/.local/state/water"

	if [ ! -f "$HOME/.local/state/water/water.db" ]; then
		sqlite3 "$HOME/.local/state/water/water.db" "create table devices (device_id text, device_type text)"
		meID=$(uuidgen -r)
		sqlite3 "$HOME/.local/state/water/water.db" "insert into devices values('$meID', 'me')"
		sqlite3 "$HOME/.local/state/water/water.db" "create table intakes (date text, time text, amount int, drink text, device_id text, clock int)"
	fi
}

drunk() {
	waterInit

	. "$HOME/.config/sh/waterToken"

	if [ "$1" = 'sync' ]; then
		meID=$(sqlite3 "$HOME/.local/state/water/water.db" -noheader "select device_id from devices where device_type = 'me'" 2>/dev/null)

		worldView=$(sqlite3 "$HOME/.local/state/water/water.db" -noheader "select 'h:' || device_id || ':' || max(clock) from intakes group by device_id" 2>/dev/null)
		world=$(curl -s -XPUT https://monitoring.apiote.xyz/life -H"Authorization: $lifeToken" -d "$worldView")

		intakeUpdates=""
		for line in $world
		do
			case "$line" in
				w*)
					deviceID=$(echo "$line" | cut -d ':' -f 2)
					clock=$(echo "$line" | cut -d ':' -f 3)
					intakes="$(sqlite3 "$HOME/.local/state/water/water.db" -noheader -list "select 'u:' || device_id || ':' || clock || ':' || date || 'T' || time || ':' || amount || ':' || drink || char(10) from intakes where device_id = '$deviceID' and clock >= $clock" 2>/dev/null)"
					intakeUpdates="${intakeUpdates} ${intakes}"
				;;
				u*)
					deviceID=$(echo "$line" | cut -d ':' -f 2)
					clock=$(echo "$line" | cut -d ':' -f 3)
					datetime=$(echo "$line" | cut -d ':' -f 4)
					date=$(echo "$datetime" | cut -d 'T' -f 1)
					time=$(echo "$datetime" | cut -d 'T' -f 2)
					amount=$(echo "$line" | cut -d ':' -f 5)
					drink=$(echo "$line" | cut -d ':' -f 6)
					sqlite3 "$HOME/.local/state/water/water.db" "insert into intakes values('$date', '$time', $amount, '$drink', '$deviceID', '$clock')" 2>/dev/null
				# TODO insert into devices
				;;
			esac
		done

		updateLines=$(echo "$intakeUpdates" | sed 's/ /\n/g')
		curl -s -XPUT https://monitoring.apiote.xyz/life -H"Authorization: $lifeToken" -d "$updateLines"

		exit
	fi

	if [ -z "$1" ]; then
		today=$(date '+%Y%m%d')
	else
		today="$1"
	fi
	sqlite3 "$HOME/.local/state/water/water.db" -noheader "select amount, drink, time from devices join intakes using(device_id) where device_type = 'me' and date = '$today'" 2>/dev/null

}

drank() {
	waterInit

	if [ -z "$1" ] || [ -z "$2" ]; then
		echo 'usage drank <amount> <drink> [time]'
		exit 1
	fi
	if echo "$1" | grep -Eq '^[0-9]+ml$'; then
		amount=$(echo "$1" | grep -Eq '^[0-9]+')
	elif echo "$1" | grep -Eq '^[0-9.]+$'; then
		amount=$(echo "$1" | grep -Eo '^([0-9]+(\.[0-9]+)?)|(\.[0-9]+)$')
		amount=$(echo "$amount 1000 * p" | dc)
	else
		case "$1" in
			glass) amount=100 ;;
			cup) amount=250 ;;
			Cup) amount=300 ;;
			can) amount=330 ;;
			mug) amount=400 ;;
			Mug) amount=500 ;;
			bottle) amount=700 ;;
		esac
	fi
	if [ -z "$3" ]; then
		date=$(date '+%Y%m%d')
		time=$(date '+%H%M%S')
	else
		date=$(echo "$3" | cut -c -8)
		time="$(echo "$3" | cut -c 9-12)00"
	fi
	meID=$(sqlite3 "$HOME/.local/state/water/water.db" -noheader "select device_id from devices where device_type = 'me'" 2>/dev/null)
	clock=$(sqlite3 "$HOME/.local/state/water/water.db" -noheader "select max(clock)+1 from intakes where device_id = '$meID'" 2>/dev/null)
	[ -z "$clock" ] && clock=1
	sqlite3 "$HOME/.local/state/water/water.db" "insert into intakes values('$date', '$time', $amount, '$2', '$meID', '$clock')" 2>/dev/null
	echo "ok, drank ${amount} ml $2"
}

lock_listen() {
	inotifywait -m -e delete /dev/ --format '%f' 2>/dev/null | while read -r dev
	do
		if [ "$dev" = 'solokey' ]; then
			serials=$(lsusb -d 0x0483:0xa2ca -v 2>/dev/null | grep Serial | tr -s ' ' | cut -d ' ' -f 4)
			for serial in $serials
			do
				if [ "$serial" = '208937A0324B' ] || [ "$serial" = '20833771324B' ]; then
					continue
				fi
			done
			pgrep swaylock >/dev/null 2>&1 || swaylock -f
		fi
	done
}

gmi() {
	gemget -o - "$1" | ~/Code/dwd/gmitohtml/gmitohtml -hostname "$1"
}

render_bar_bluetooth() {
	if bluetoothctl info | grep -E '(Connected)' | grep -q 'yes' >/dev/null 2>&1; then
		printf "<span color='#00afff'>█</span>"
	elif bluetoothctl show | grep Powered | grep -q 'yes' >/dev/null 2>&1; then
		printf "<span color='#00afff'>░</span>"
	else
		printf ''
	fi
}


bar_bluetooth() {
	mpv_count=$(cat /tmp/mpv_count 2>/dev/null)
	mpv_count=${mpv_count:-0}

	if [ -e /tmp/swaybar/pipe ] && [ "$mpv_count" -eq 0 ]; then
		printf "bluetooth|%s\n" "$(render_bar_bluetooth)" >/tmp/swaybar/pipe
	fi
}

say() {
	if [ -z "$1" ]; then
		larynx -m /usr/share/larynx2/en/us/glados/en-us-glados-high.onnx 2>/dev/null
	else
		echo "$@" | larynx -m /usr/share/larynx2/en/us/glados/en-us-glados-high.onnx 2>/dev/null
	fi
}

signImage() {
	if ! ls /media/nextcloud/me@cloud.apiote.xyz/Pictutes/IDs/logo/waterSign.svg >/dev/null 2>&1; then
		echo 'water sign not mounted'
		exit 1
	fi

  width=$(ffprobe "$1" -show_entries stream=width -of csv=p=0 -v error -select_streams v:0)
  waterWidth=$(echo "$width 3 / p" | dc);
  height=$(ffprobe "$1" -show_entries stream=height -of csv=p=0 -v error -select_streams v:0)
  inkscape -w "$waterWidth" --export-filename=waterSign.png /media/nextcloud/me@cloud.apiote.xyz/Pictutes/IDs/logo/waterSign.svg
  waterHeight=$(ffprobe waterSign.png -show_entries stream=height -of csv=p=0 -v error -select_streams v:0)
  y=$(echo "$height 100 - $waterHeight - p" | dc)
  magick \( -page +0+0 "$1" \) \( -page "+100+$y" waterSign.png \) -flatten "$1.signed.jpg"
	rm waterSign.png
}

autoBrightness() {
	min_il=0
	monitor-sensor --light | while read -r line
	do
		ilumination=$(echo "$line" | grep 'Light changed' | tr -s ' ' | cut -d ' ' -f 3)
		if [ -z "$ilumination" ]; then
			continue
		fi
		brightness=$(echo "scale=2; l($ilumination - $min_il + 1) * 3" | fun bc | cut -d '.' -f1)
		brightness=${brightness:-0}
		if [ "$brightness" -gt 100 ]; then
			brightness=100
		elif [ "$brightness" -lt 0 ]; then
			brightness=0
		fi
		brillo -u 1000000 -S "$brightness"
	done
}

barHider() {
	# TODO subscribe to workspace too, but jq throws some error
	swaymsg -t subscribe -m "['window']" | script -O /dev/null -E never -q -f -c "jq '[.change, .container.app_id] | @csv' -r" | while read -r line
	do
		change=$(echo "$line" | cut -d',' -f1 | tr -d '"')
		app=$(echo "$line" | cut -d',' -f2 | tr -d '"' | sed 's/\r//')

		if [ "$app" = 'null' ] || { [ "$app" = 'mpv' ] && { [ "$change" = 'fullscreen_mode' ] || [ "$change" = 'close' ]; }; }; then
			if swaymsg -t get_tree -r | jq '.. | objects | select(.app_id == "mpv") | [ .focused, .fullscreen_mode ] | @csv' | grep -q 'true,1'; then
				swaymsg bar mode dock
			else
				swaymsg bar mode overlay
			fi
		fi
	done
}

bc() {
	/usr/local/bin/bc -c -l /usr/lib/plan9/lib/bclib | dc | tail -n1
}
